package com.lifeverse.entity;

import com.lifeverse.entity.enums.AuditAction;
import com.lifeverse.entity.enums.AuditResult;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;

import java.time.LocalDateTime;

/**
 * 审计日志实体
 * 记录系统中所有重要操作的审计信息
 */
@Entity
@Table(name = "audit_logs", indexes = {
    @Index(name = "idx_audit_user", columnList = "user_id"),
    @Index(name = "idx_audit_action", columnList = "action"),
    @Index(name = "idx_audit_timestamp", columnList = "timestamp"),
    @Index(name = "idx_audit_resource", columnList = "resource_type, resource_id"),
    @Index(name = "idx_audit_result", columnList = "result"),
    @Index(name = "idx_audit_ip", columnList = "ip_address")
})
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AuditLog extends BaseEntity {
    
    /**
     * 用户ID（可能为空，表示系统操作）
     */
    @Column(name = "user_id", length = 50)
    private String userId;
    
    /**
     * 用户名（可能为空，表示系统操作）
     */
    @Column(name = "username", length = 100)
    private String username;
    
    /**
     * 操作类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "action", nullable = false, length = 50)
    private AuditAction action;
    
    /**
     * 资源类型
     */
    @Column(name = "resource_type", length = 100)
    private String resourceType;
    
    /**
     * 资源ID
     */
    @Column(name = "resource_id", length = 50)
    private String resourceId;
    
    /**
     * 操作描述
     */
    @Column(name = "description", length = 500)
    private String description;
    
    /**
     * 操作结果
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "result", nullable = false, length = 20)
    private AuditResult result;
    
    /**
     * 错误信息（如果操作失败）
     */
    @Column(name = "error_message", length = 1000)
    private String errorMessage;
    
    /**
     * 客户端IP地址
     */
    @Column(name = "ip_address", length = 45)
    private String ipAddress;
    
    /**
     * 用户代理
     */
    @Column(name = "user_agent", length = 500)
    private String userAgent;
    
    /**
     * 会话ID
     */
    @Column(name = "session_id", length = 100)
    private String sessionId;
    
    /**
     * 请求URI
     */
    @Column(name = "request_uri", length = 500)
    private String requestUri;
    
    /**
     * HTTP方法
     */
    @Column(name = "http_method", length = 10)
    private String httpMethod;
    
    /**
     * 请求参数（敏感信息已过滤）
     */
    @Column(name = "request_params", columnDefinition = "TEXT")
    private String requestParams;
    
    /**
     * 响应状态码
     */
    @Column(name = "response_status")
    private Integer responseStatus;
    
    /**
     * 操作耗时（毫秒）
     */
    @Column(name = "duration_ms")
    private Long durationMs;
    
    /**
     * 操作时间戳
     */
    @Column(name = "timestamp", nullable = false)
    private LocalDateTime timestamp;
    
    /**
     * 额外的上下文信息（JSON格式）
     */
    @Column(name = "context_data", columnDefinition = "TEXT")
    private String contextData;
    
    /**
     * 风险等级（1-5，5为最高风险）
     */
    @Column(name = "risk_level")
    private Integer riskLevel;
    
    /**
     * 是否为敏感操作
     */
    @Column(name = "is_sensitive")
    private Boolean isSensitive;
    
    /**
     * 创建审计日志的静态方法
     */
    public static AuditLog create(String userId, String username, AuditAction action, 
                                 String resourceType, String resourceId, String description) {
        return AuditLog.builder()
                .userId(userId)
                .username(username)
                .action(action)
                .resourceType(resourceType)
                .resourceId(resourceId)
                .description(description)
                .result(AuditResult.SUCCESS)
                .timestamp(LocalDateTime.now())
                .riskLevel(1)
                .isSensitive(false)
                .build();
    }
    
    /**
     * 创建失败的审计日志
     */
    public static AuditLog createFailure(String userId, String username, AuditAction action,
                                        String resourceType, String resourceId, String description,
                                        String errorMessage) {
        return AuditLog.builder()
                .userId(userId)
                .username(username)
                .action(action)
                .resourceType(resourceType)
                .resourceId(resourceId)
                .description(description)
                .result(AuditResult.FAILURE)
                .errorMessage(errorMessage)
                .timestamp(LocalDateTime.now())
                .riskLevel(3)
                .isSensitive(false)
                .build();
    }
    
    /**
     * 设置请求信息
     */
    public AuditLog withRequestInfo(String ipAddress, String userAgent, String sessionId,
                                   String requestUri, String httpMethod, String requestParams) {
        this.ipAddress = ipAddress;
        this.userAgent = userAgent;
        this.sessionId = sessionId;
        this.requestUri = requestUri;
        this.httpMethod = httpMethod;
        this.requestParams = requestParams;
        return this;
    }
    
    /**
     * 设置响应信息
     */
    public AuditLog withResponseInfo(Integer responseStatus, Long durationMs) {
        this.responseStatus = responseStatus;
        this.durationMs = durationMs;
        return this;
    }
    
    /**
     * 设置风险等级
     */
    public AuditLog withRiskLevel(Integer riskLevel) {
        this.riskLevel = riskLevel;
        return this;
    }
    
    /**
     * 标记为敏感操作
     */
    public AuditLog markAsSensitive() {
        this.isSensitive = true;
        this.riskLevel = Math.max(this.riskLevel != null ? this.riskLevel : 1, 3);
        return this;
    }
}